package nickthissen.iracing.activities;

import nickthissen.iracing.adapters.PagerAdapter;
import nickthissen.iracing.common.Cache;
import nickthissen.iracing.common.DataLoader;
import nickthissen.iracing.common.DateUtils;
import nickthissen.iracing.common.ForumListManager;
import nickthissen.iracing.common.Prefs;
import nickthissen.iracing.common.Redirect;
import nickthissen.iracing.common.ServiceLogging;
import nickthissen.iracing.common.Sharing;
import nickthissen.iracing.common.Task;
import nickthissen.iracing.common.WebViewUtil;
import nickthissen.iracing.datamodels.FavoriteThread;
import nickthissen.iracing.datamodels.Forum;
import nickthissen.iracing.datamodels.Page;
import nickthissen.iracing.datamodels.Post;
import nickthissen.iracing.datamodels.PostList;
import nickthissen.iracing.datamodels.Result;
import nickthissen.iracing.datamodels.Thread;
import nickthissen.iracing.common.Error;
import nickthissen.iracing.datamodels.User;
import nickthissen.iracing.iracingforum2.R;
import nickthissen.iracing.networking.Networking;
import nickthissen.iracing.parsing.Parser;
import nickthissen.iracing.parsing.ThreadParser;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.internal.widget.IcsAdapterView;
import com.actionbarsherlock.internal.widget.IcsSpinner;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuItem;
import com.actionbarsherlock.view.Window;

import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

public class ThreadActivity extends TaskActivity
{
	private static final String URL = "URL";
    private static final String STORED_URL = "STORED_URL";
	private static final String LAST_PAGE = "LAST_PAGE";
	private static final String THREAD = "THREAD";
	private static final String FORUM_ID = "FORUM_ID";
    private static final Integer NEWPOST = 1;

    private PostList postList;
    private ProgressDialog dialog;
    //private TextView lblPage;

    private ArrayList<Page> pages;
    private IcsSpinner pageSpinner;

    private Button btnPost;
    private ImageButton btnPrevPage, btnNextPage, btnFirstPage, btnLastPage;
    private LinearLayout pageLayout, pollLayout;
    private WebView webContents, webPoll;

    private String currentUrl, storedUrl;
    private Thread thread;
    private Forum forum;

    private Task<String> nextPageTask, prevPageTask;

    private boolean fromRedirect;
    private boolean lastPage;
    private boolean showDate = false;
	
	@Override
    public void onCreate(Bundle savedInstanceState) 
    {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_PROGRESS);

        SherlockUtils.setNotificationBar(this);

        setContentView(R.layout.postlist);

        getSupportActionBar().setDisplayShowHomeEnabled(false);

        //lblPage = (TextView) this.findViewById(R.id.lblPage);
        pageSpinner = (IcsSpinner) this.findViewById(R.id.pageSpinner);

        btnPrevPage = (ImageButton) this.findViewById(R.id.btnPrevPage);
        btnNextPage = (ImageButton) this.findViewById(R.id.btnNextPage);
        btnFirstPage = (ImageButton) this.findViewById(R.id.btnFirstPage);
        btnLastPage = (ImageButton) this.findViewById(R.id.btnLastPage);
        pageLayout = (LinearLayout) this.findViewById(R.id.pageLayout);
        //pollLayout = (LinearLayout) this.findViewById(R.id.pollLayout);
        webContents = (WebView) this.findViewById(R.id.webContents);
        //webPoll = (WebView) this.findViewById(R.id.webPoll);

        webContents.setWebViewClient(new ThreadWebViewClient(this));
        webContents.getSettings().setJavaScriptEnabled(true);
        webContents.getSettings().setSupportZoom(false);
        webContents.setWebChromeClient(new WebChromeClient()
        {
            @Override
            public void onProgressChanged(WebView view, int newProgress)
            {
                setSupportProgress(newProgress * 100);
                super.onProgressChanged(view, newProgress);
            }
        });

        WebViewUtil.syncCookies(webContents);

        btnPrevPage.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                previousPage();
            }
        });

        btnNextPage.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                nextPage();
            }
        });

        btnFirstPage.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                firstPage();
            }
        });

        btnLastPage.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                lastPage();
            }
        });

        showDate = Prefs.get(this).getBoolean(R.string.PREF_PostListShowDate, true);

        Bundle extras = savedInstanceState;
        if (extras == null)
        {
            Intent i = this.getIntent();
            extras = i.getExtras();
        }
        lastPage = extras.getBoolean(LAST_PAGE);

        thread = null;
        if (extras.containsKey(THREAD))
        {
            thread = (Thread) extras.getSerializable(THREAD);
        }

        if (thread == null)
        {
            // Thread opened from redirect
            fromRedirect = true;
            currentUrl = extras.getString(URL);
        }
        else
        {
            // Regularly opened
            fromRedirect = false;

            int id = extras.getInt(FORUM_ID);
            forum = ForumListManager.getInstance().forums.get(id);

            if (lastPage && thread.LatestReplyUrl != null && !thread.LatestReplyUrl.trim().equals(""))
                currentUrl = thread.LatestReplyUrl;
            else
                currentUrl = thread.Url;

            setThreadTitle(thread.Title);
        }

        this.loadPostList(currentUrl);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getSupportMenuInflater().inflate(R.menu.thread, menu);
        this.prepareWatchMenuItem(menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item)
    {
        switch (item.getItemId()) {
            case R.id.mnuPost:
                this.newPost();
                return true;
            case R.id.mnuRefresh:
                Cache.removeThread(currentUrl);
                this.loadPostList(currentUrl);
                return true;
            case R.id.mnuShare:
                Sharing.shareForumUrl(this, currentUrl);
                return true;
            case R.id.mnuFavorite:
                this.addFavorite(thread);
                return true;
            case R.id.mnuWatch:
                this.watch();
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu)
    {
        this.prepareWatchMenuItem(menu);
        return super.onPrepareOptionsMenu(menu);
    }

    private void prepareWatchMenuItem(Menu menu)
    {
        MenuItem item = menu.findItem(R.id.mnuWatch);
        if (item != null)
        {
            if (thread != null)
            {
                if (thread.IsWatching)
                    item.setTitle(R.string.unwatch);
                else
                    item.setTitle(R.string.watchthread);
            }
        }
    }

    @Override
    protected Task<String> createTask()
    {
        return new Task<String>(this, postLoader);
    }

    @Override
    protected void saveTaskInput(Bundle state)
    {
        state.putString(STORED_URL, storedUrl);
    }

    @Override
    public Object restoreTaskInput(Bundle state)
    {
        return state.getString(STORED_URL);
    }

    @Override
    public void onSaveInstanceState(Bundle outState)
    {
        outState.putBoolean(LAST_PAGE, lastPage);
        outState.putSerializable(THREAD, thread);
        outState.putString(URL, currentUrl);

        int forumId = 0;
        if (forum != null) forumId = forum.Id;
        outState.putInt(FORUM_ID, forumId);
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onRestoreInstanceState(Bundle state)
    {
        lastPage = state.getBoolean(LAST_PAGE);
        thread = (Thread) state.getSerializable(THREAD);
        currentUrl = state.getString(URL);

        int id = state.getInt(FORUM_ID);
        forum = ForumListManager.getInstance().forums.get(id);

        super.onRestoreInstanceState(state);
    }

	public static Intent getRedirectIntent(Context context, String redirectUrl)
	{
		Bundle bundle = new Bundle();
		bundle.putString(URL, redirectUrl);
		bundle.putBoolean(LAST_PAGE, false);
		
		Intent intent = new Intent(context, ThreadActivity.class);
		intent.putExtras(bundle);
		
		return intent;
	}
	
	public static Intent getIntent(Context context, Thread thread, int forumId, boolean lastPage)
	{
		Bundle bundle = new Bundle();
		bundle.putSerializable(THREAD, thread);
		bundle.putInt(FORUM_ID, forumId);
		bundle.putBoolean(LAST_PAGE, lastPage);
		
		Intent intent = new Intent(context, ThreadActivity.class);
		intent.putExtras(bundle);
		
		return intent;
	}

    private void setThreadTitle(String title)
    {
        SherlockUtils.setMultilineTitle(this, title);
    }

    private void cancelAllTasks()
    {
        // Cancel primary loading task
        this.onCancelTask();

        // Cancel next/previous page caching task
        if (nextPageTask != null) nextPageTask.cancel(true);
        if (prevPageTask != null) prevPageTask.cancel(true);
    }

    private void loadPostList(String url)
    {
        if (fromRedirect)
        {
            this.loadRegular(url);
        }
        else
        {
            this.loadFromCache(url);
        }
        ServiceLogging.logPageRequest(this, url);
    }

    private void loadFromCache(String url)
    {
        boolean allowCache = Prefs.get(this).getBoolean(R.string.PREF_ThreadCaching, true);
        if (allowCache)
        {
            PostList cached = Cache.loadThread(url);
            if (cached != null)
            {
                setContents(cached);
                loadBackground(url);
                return;
            }
        }
        this.loadRegular(url);
    }

    private void loadRegular(String url)
    {
        dialog = ProgressDialog.show(this, "Loading", "Loading posts...");
        dialog.setCancelable(true);
        dialog.setCanceledOnTouchOutside(false);
        dialog.setOnCancelListener(new DialogInterface.OnCancelListener()
        {
            @Override
            public void onCancel(DialogInterface d)
            {
                task.cancel(true);
                d.dismiss();
            }
        });

        // Don't load in background
        storedUrl = url;
        this.runTask(url);
    }

    private void loadBackground(String url)
    {
        SherlockUtils.setProgressVisibility(this, true);
        SherlockUtils.setRefreshButtonVisibility(this, false);

        new Task<String>(this, postCacheLoader).execute(url);
    }

    private void backgroundFinished(final String url, boolean success)
    {
        SherlockUtils.setProgressVisibility(this, false);
        if (success)
        {
            SherlockUtils.setRefreshButtonVisibility(this, true);
            ImageButton button = SherlockUtils.getRefreshButton(this);
            button.setOnClickListener(new View.OnClickListener()
            {
                @Override
                public void onClick(View v)
                {
                    refreshFromCache(url);
                }
            });
        }
    }

    private void refreshFromCache(String url)
    {
        PostList cached = Cache.loadThread(url);
        if (cached != null)
        {
            setContents(cached);
        }
        SherlockUtils.setRefreshButtonVisibility(this, false);
    }


    private void setContents(PostList list)
    {
        postList = list;
        setPagination();
        setContents(postList.Posts);

        // Start loading next/prev page task for caching
        if (postList.HasPagination)
        {
            if (postList.Page < postList.LastPage)
            {
                nextPageTask = new Task<String>(this, nextPrevPageLoader);
                nextPageTask.execute(postList.NextPageUrl);
            }
            if (postList.Page > 1)
            {
                // If already cached previous page, don't bother
                if (Cache.loadThread(postList.PreviousPageUrl) == null)
                {
                    prevPageTask = new Task<String>(this, nextPrevPageLoader);
                    prevPageTask.execute(postList.PreviousPageUrl);
                }
            }
        }
    }

    private void setContents(ArrayList<Post> posts)
    {
        if (thread == null) return;

        StringBuilder builder = new StringBuilder();

        // HTML
        builder.append("<html><head><link rel=\"stylesheet\" href=\"file:///android_asset/style.css\" type=\"text/css\">");
        builder.append("</link>");
        builder.append("<script>");
        builder.append("function scrollAnchor(id) {");
        builder.append("window.location.hash = id;}");
        builder.append("</script>");
        builder.append("</head><body>");
        builder.append(getThreadBody(posts));
        builder.append("</body></html>");

        webContents.loadDataWithBaseURL("file:///android_asset/", builder.toString(), "text/html", "utf-8", null);

        if (lastPage && !thread.LatestReplyUrl.equals(""))
        {
            Timer timer = new Timer();
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    int hashLoc = thread.LatestReplyUrl.lastIndexOf('#');
                    if (hashLoc > 0)
                    {
                        int id = Integer.parseInt(thread.LatestReplyUrl.substring(hashLoc + 1));
                        webContents.loadUrl("javascript:scrollAnchor(" + id + ");");
                    }
                }
            }, 250);
        }
    }

    private String getThreadBody(ArrayList<Post> posts)
    {
        if (thread == null) return "";

        StringBuilder builder = new StringBuilder();

        for (int i = 0; i < posts.size(); i++)
        {
            Post post = posts.get(i);

            builder.append("<div class=\"post\">");

            if (showDate)
            {
                builder.append("<div class=\"authordate\"><div class=\"authorinner\">");
            }
            else
            {
                builder.append("<div class=\"author\"><div class=\"authorinner\">");
            }

            String nameClass = "name";
            if (post.AuthorDonated) nameClass = "donatedname";
            if (post.AuthorIsStaff) nameClass = "staffname";

            builder.append("<div class=\"" + nameClass + "\">");

            if (post.AuthorDonated)
            {
                builder.append("<a name=\"" + post.Id + "\" href=\"http://iracingforum.nickthissen.nl/Donate.aspx\">");
                //builder.append("<img src=\"money.png\" />");
            }
            else
            {
                builder.append("<a name=\"" + post.Id + "\">");
            }

            if (post.IsIgnored)
            {
                builder.append("<div class=\"ignored\">");
                builder.append(post.IgnoredText);
                builder.append("</div>");
            }
            else
            {
                builder.append(post.Author);
            }
            builder.append("</a>");
            builder.append("</div>");

            if (postList.CanReply && !post.IsIgnored)
            {
                builder.append("<div class=\"authorcontrol\">");

                builder.append("<a href=\"quote_" + i + "\">Quote</a>");
                if (post.CanEdit)
                {
                    builder.append("&nbsp;<a href=\"edit_" + i + "\">Edit</a>");
                }
                builder.append("</div>");
            }

            builder.append("<div class=\"clear\" />");

            if (showDate && !post.IsIgnored)
            {
                builder.append("<div class=\"date\">");
                builder.append(DateUtils.UnixMsToString(post.CreatedTime));
                builder.append("</div>");
            }

            builder.append("</div></div></div>");

            builder.append("<div class=\"contentheader\"></div>");
            if (!post.IsIgnored)
            {
                builder.append("<div class=\"content\">");
                builder.append(post.Contents);
                builder.append("</div><div class=\"contentfooter\">");
                builder.append("</div>");
            }
            builder.append("</div>");
        }

        return builder.toString();
    }

    private boolean isInitialized = false;

    private void setPagination()
    {
        if (postList == null) return;

        isInitialized = false;
        pages = Page.fromList(postList);

        if (!postList.HasPagination)
        {
            pageLayout.setVisibility(View.GONE);
        }
        else
        {
            pageLayout.setVisibility(View.VISIBLE);

            pageSpinner.setAdapter(new PagerAdapter(this, 0, pages));
            pageSpinner.setSelection(postList.Page - 1);

            pageSpinner.setOnItemSelectedListener(new IcsAdapterView.OnItemSelectedListener()
            {
                @Override
                public void onItemSelected(IcsAdapterView<?> parent, View view, int position, long id)
                {
                    if (!isInitialized)
                    {
                        isInitialized = true;
                        return;
                    }

                    if (position >= 0 && position < pages.size())
                    {
                        Page page = pages.get(position);
                        String url = page.getThreadUrl(currentUrl);
                        changePage(url);
                    }
                }

                @Override
                public void onNothingSelected(IcsAdapterView<?> parent)
                {
                }
            });

            btnPrevPage.setEnabled(postList.Page > 1);
            btnNextPage.setEnabled(postList.Page < postList.LastPage);

            btnFirstPage.setEnabled(postList.Page > 1);
            btnLastPage.setEnabled(postList.Page < postList.LastPage);
        }
    }

    private void changePage(String url)
    {
        this.cancelAllTasks();

        isInitialized = false;
        currentUrl = url;
        this.loadPostList(url);
    }

    private void previousPage()
    {
        if (postList == null) return;
        this.changePage(postList.PreviousPageUrl);
    }

    private void nextPage()
    {
        if (postList == null) return;
        this.changePage(postList.NextPageUrl);
    }

    private void firstPage()
    {
        if (postList == null) return;
        this.changePage(thread.Url);
    }

    private void lastPage()
    {
        if (postList == null) return;
        this.changePage(postList.ThreadLastPageUrl);
    }

    private void newPost()
    {
        if (postList == null || thread == null) return;
        this.cancelAllTasks();
        if (!postList.CanReply)
        {
            Toast.makeText(this, "You cannot reply to this thread.", Toast.LENGTH_SHORT).show();
            return;
        }

        Intent intent = PostActivity.getPostIntent(this, forum.Id, thread.Id);
        this.startActivityForResult(intent, NEWPOST);
    }

    private void quotePost(int index)
    {
        if (postList == null || thread == null) return;
        this.cancelAllTasks();
        if (!postList.CanReply)
        {
            Toast.makeText(this, "You cannot reply to this thread.", Toast.LENGTH_SHORT).show();
            return;
        }

        Post post = postList.Posts.get(index);

        Intent intent = PostActivity.getQuoteIntent(this, forum.Id, thread.Id, post.QuoteUrl);
        this.startActivityForResult(intent, NEWPOST);
    }

    private void editPost(int index)
    {
        if (postList == null || thread == null) return;
        this.cancelAllTasks();

        Post post = postList.Posts.get(index);

        Intent intent = PostActivity.getEditIntent(this, forum.Id, thread.Id, post.Id, post.EditUrl);
        this.startActivityForResult(intent, NEWPOST);
    }

    private void watch()
    {
        if (thread == null) return;
        this.cancelAllTasks();

        new Task<Thread>(this, new DataLoader<Thread>()
        {
            @Override
            public Result getData(Thread in)
            {
                Networking.toggleWatchThread(this.getContext(), in);
                return Result.ok(in.IsWatching);
            }

            @Override
            public void onFinished(Result out)
            {
                String msg;
                if ((Boolean)out.Object)
                    msg = "You are now watching this thread.";
                else
                    msg = "You are no longer watching this thread.";
                Toast.makeText(this.getContext(), msg, Toast.LENGTH_LONG).show();
            }
        }).execute(thread);
    }

    public boolean addFavorite(Thread item)
    {
        DialogClickListener clickListener = new DialogClickListener(this, item);
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setMessage("Do you want to add this thread to your favorites?")
                .setPositiveButton("Yes", clickListener)
                .setNegativeButton("No", clickListener)
                .show();
        return true;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent)
    {
        super.onActivityResult(requestCode, resultCode, intent);

        if (resultCode == RESULT_OK && requestCode == NEWPOST)
        {
            Cache.removeThread(thread.LastPageUrl);
            Cache.removeThread(thread.Url);
            this.loadPostList(thread.LastPageUrl);
        }
    }

    private class DialogClickListener implements DialogInterface.OnClickListener
    {
        Activity context;
        Thread thread;
        FavoriteThread favorite;

        public DialogClickListener(Activity context, Thread thread)
        {
            this.context = context;
            this.thread = thread;
            this.favorite = FavoriteThread.fromThread(thread, User.currentUser.username);
        }

        @Override
        public void onClick(DialogInterface dialog, int which)
        {
            if (which == DialogInterface.BUTTON_POSITIVE)
            {
                new Task<FavoriteThread>(context, new DataLoader<FavoriteThread>()
                {
                    @Override
                    public Result getData(FavoriteThread in)
                    {
                        return Networking.addFavorite(this.getContext(), User.currentUser, in);
                    }

                    @Override
                    public void onFinished(Result out)
                    {
                        if (out.Success)
                        {
                            Toast.makeText(context, "Favorite saved.", Toast.LENGTH_SHORT).show();
                        }
                        else
                        {
                            Error.fromResult(out).report(this.getContext());
                        }
                    }
                }).execute(favorite);
            }
            dialog.dismiss();
        }
    }

    private DataLoader<String> postLoader = new DataLoader<String>()
    {
        public boolean cacheOnly = false;
        private String url;

        @Override
        public Result getData(String in)
        {
            url = in;

            // Obtain thread page source
            Result result = Networking.getPostList(this.getContext(), in);

            if (result.Success)
            {
                // Parse
                String source = (String)result.Object;
                Parser parser = new ThreadParser();
                return parser.parse(source);
            }
            else
            {
                // Error
                return result;
            }
        }

        @Override
        public void onFinished(Result out)
        {
            if (out.Success)
            {
                postList = (PostList)out.Object;
                setPagination();
            }
            else
            {
                // Error
                postList = new PostList();
                postList.Posts = new ArrayList<Post>();

                Error.fromResult(out).report(this.getContext());
            }

            if (!postList.CanReply)
            {
                // TODO: hide reply button
            }

            if (fromRedirect)
            {
                thread = new Thread();
                thread.Id = postList.ThreadId;
                thread.Url = postList.ThreadUrl;
                thread.LastPageUrl = postList.ThreadLastPageUrl;
                thread.Title = postList.ThreadTitle;

                forum = new Forum();
                forum.Id = postList.ForumId;
                forum.Url = postList.ForumUrl;
                forum.Title = postList.ForumTitle;

                setThreadTitle(thread.Title);

                invalidateOptionsMenu();
            }

            thread.IsWatching = postList.IsWatching;

            setContents(postList);

            if (dialog != null)
            {
                dialog.dismiss();
                dialog = null;
            }

            Cache.saveThread(postList, url);
        }
    };

    private DataLoader<String> postCacheLoader = new DataLoader<String>()
    {
        private String url;

        @Override
        public Result getData(String in)
        {
            url = in;

            // Obtain thread page source
            Result result = Networking.getPostList(this.getContext(), in);

            if (result.Success)
            {
                // Parse
                String source = (String)result.Object;
                Parser parser = new ThreadParser();
                return parser.parse(source);
            }
            else
            {
                // Error
                return result;
            }
        }

        @Override
        public void onFinished(Result out)
        {
            if (out.Success)
            {
                Cache.saveThread((PostList)out.Object, url);
            }
            else
            {
                Error.fromResult(out).report(this.getContext());
            }
            backgroundFinished(url, out.Success);
        }
    };

    private DataLoader<String> nextPrevPageLoader = new DataLoader<String>()
    {
        private String url;

        @Override
        public Result getData(String in)
        {
            url = in;

            // Obtain thread page source
            Result result = Networking.getPostList(this.getContext(), in);

            if (result.Success)
            {
                // Parse
                String source = (String)result.Object;
                Parser parser = new ThreadParser();
                return parser.parse(source);
            }
            else
            {
                // Error
                return result;
            }
        }

        @Override
        public void onFinished(Result out)
        {
            if (out.Success)
            {
                PostList list = (PostList)out.Object;
                Cache.saveThread(list, url);
            }
        }
    };

    private class ThreadWebViewClient extends WebViewClient
    {
        private ThreadActivity activity;
        private final String QUOTE_URL = "file:///android_asset/quote_";
        private final String EDIT_URL = "file:///android_asset/edit_";
        private final String IMG_ATTACH_URL = "http://members.iracing.com/jforum/posts/downloadAttach/";
        private final String LINK_ATTACH_URL = "file:///android_asset/link_";
        private final String FORUM_URL = "http://members.iracing.com/jforum/";
        private final String FORUMLIST_URL = "http://members.iracing.com/jforum/forums/list.page";

        public ThreadWebViewClient(ThreadActivity activity)
        {
            this.activity = activity;
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            Log.i("WebViewClient", "Overriding URL: " + url);
            if (url.startsWith(QUOTE_URL))
            {
                // Quote
                int length = QUOTE_URL.length();
                String sub = url.substring(length);
                int index = Integer.parseInt(sub);
                activity.quotePost(index);

                return true;
            }
            else if (url.startsWith(EDIT_URL))
            {
                // Edit
                int length = EDIT_URL.length();
                String sub = url.substring(length);
                int index = Integer.parseInt(sub);
                activity.editPost(index);

                return true;
            }
			else if (url.startsWith(IMG_ATTACH_URL))
			{
				activity.startActivity(WebActivity.getIntent(activity, url, "View image"));
                return true;
			}
            else if (url.startsWith(LINK_ATTACH_URL))
            {
                // Download attachment
                int length = LINK_ATTACH_URL.length();
                String sub = url.substring(length);
                Toast.makeText(activity, "Unable to download files at this time...", Toast.LENGTH_LONG).show();

                return true;
            }
            else if (url.startsWith(FORUM_URL))
            {
                // Link to another thread
                Uri uri = Uri.parse(url);
                Redirect redirect = Redirect.handleData(uri);
                if (redirect != null)
                {
                    Redirect.loadRedirect(activity, redirect);
                }

                return true;
            }

            // Fall back to default behavior
            activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
            return true;
        }
    }
}
